package com.tarena.lbs.coupon.service.impl;

import com.tarena.lbs.activity.api.ActivityApi;
import com.tarena.lbs.activity.api.pojo.ActivityDto;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.coupon.api.pojo.param.UserCouponsParam;
import com.tarena.lbs.coupon.dao.repository.CouponCodeRepository;
import com.tarena.lbs.coupon.dao.repository.CouponRepository;
import com.tarena.lbs.coupon.dao.repository.StockRepository;
import com.tarena.lbs.coupon.dao.repository.UserCouponsRepository;
import com.tarena.lbs.coupon.enums.CouponStatusEnum;
import com.tarena.lbs.coupon.enums.UserCouponsStatusEnum;
import com.tarena.lbs.coupon.pojo.po.CouponCodePO;
import com.tarena.lbs.coupon.pojo.po.CouponPO;
import com.tarena.lbs.coupon.pojo.po.CouponStockPO;
import com.tarena.lbs.coupon.pojo.po.UserCouponsPO;
import com.tarena.lbs.coupon.service.StockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
public class StockServiceImpl implements StockService {

    @DubboReference
    private ActivityApi activityApi;

    @Autowired
    private CouponCodeRepository couponCodeRepository;

    @Autowired
    private StockRepository stockRepository;

    @Autowired
    private CouponRepository couponRepository;

    @Autowired
    private UserCouponsRepository userCouponsRepo;

    @Override
    @Transactional
    public void receiveCoupon(UserCouponsParam param) throws BusinessException {
        log.debug("领取优惠券业务：UserCouponsParam={}",param);
        //身份校验
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("401","身份校验失败"));
        //检查活动信息
        ActivityDto activityDto = activityApi.getActivityById(param.getActivityId());
        //活动是否存在
        Asserts.isTrue(activityDto==null,new BusinessException("404","活动不存在"));
        //参与活动时间是否在活动有效期
        Date nowDate = new Date();
        Asserts.isTrue(activityDto.getStartDate().after(nowDate) || activityDto.getEndDate().before(nowDate),
                new BusinessException("400","活动不在有效期内"));
        //校验活动状态 是否启用
        Asserts.isTrue(activityDto.getStatus()!=1,new BusinessException("400","活动已关闭"));
        //校验用户是否有参与资格
        Asserts.isTrue(activityApi.activityVisible(userPrinciple.getId(), param.getActivityId()), new BusinessException("400","用户没有参与资格"));
        //检查优惠券状态 是否启用 是否存在
        CouponPO couponPO = couponRepository.getCouponById(param.getCouponId());
        Asserts.isTrue(couponPO==null,new BusinessException("404","优惠券不存在"));
        Asserts.isTrue(couponPO.getStatus()!= CouponStatusEnum.ACTIVE.getCode(),new BusinessException("400","优惠券已关闭"));
        //检查库存
        CouponStockPO couponStockPO = stockRepository.selectByCouponId(param.getCouponId());
        Asserts.isTrue(couponStockPO==null||couponStockPO.getNum()<=0,new BusinessException("404","优惠券库存不足"));
        //领取优惠券 库存-1，获取优惠券编码，添加领取记录
        //生成优惠券编码
        CouponCodePO couponCodePO = new CouponCodePO();
        couponCodePO.setCouponId(couponPO.getId());
        couponCodePO.setCouponCode(UUID.randomUUID().toString());
        couponCodePO.setBusinessId(couponPO.getBusinessId());
        couponCodePO.setCreateAt(new Date());
        couponCodeRepository.insertCouponCode(couponCodePO);
        param.setCouponCode(couponCodePO.getCouponCode());
        //库存-1
        couponStockPO.setNum(couponStockPO.getNum()-1);
        stockRepository.saveStock(couponStockPO);
        //添加领取记录
        UserCouponsPO userCouponsPO = new UserCouponsPO();
        BeanUtils.copyProperties(param,userCouponsPO);
        userCouponsPO.setStatus(UserCouponsStatusEnum.NOT_USE.getCode());
        userCouponsPO.setCreateAt(new Date());
        userCouponsPO.setCouponType(couponPO.getCouponType());
        userCouponsPO.setCouponValue(couponPO.getDiscountValue());
        userCouponsRepo.insert(userCouponsPO);
    }
}
